//////////////////////////////////////////////////
// EASIM project
// easim.mobi.CommunityBased
// 6/23/2007 1:56 PM
// Cong Liu
// gzcong@gmail.com

// Copyright (C) 2007
// All rights reserved.
// Refer to LICENSE of JIST (Java In Simulation Time) for terms and conditions of use.

package easim.mobi;

import jist.runtime.JistAPI;
import jist.swans.Constants;
import easim.net.Node;

public class CommunityBased extends RandomWaypoint implements JistAPI.DoNotRewrite
{

  ///////////////////////////////////
  // CommunityBased
  //

  public static double TRAVEL_PROBABILITY = 0.1;

  // commnunity codes
  //  1 |   | 2 
  // ---+---+---
  //    |   |   
  // ---+---+---
  //  3 |   | 4 
  protected int community;

  public CommunityBased(Node node) {
    super(node);
    community = 1 + Constants.random.nextInt(4);
  }

  public static float nextX(int community) {
    float x = (float)(Constants.random.nextFloat() * (WIDTH / 3.0));
    if (community == 2 || community == 4) {
      x += (float)(WIDTH * 2.0 / 3.0);
    }
    return x;
  }

  public static float nextY(int community) {
    float y = (float)(Constants.random.nextFloat() * (HEIGHT / 3.0));
    if (community == 3 || community == 4) {
      y += (float)(HEIGHT * 2.0 / 3.0);
    }
    return y;
  }

  public void nextWaypoint() {
    int com = community;
    double p = Constants.random.nextDouble();
    if (p < TRAVEL_PROBABILITY) {
      while (com == community) {
        com = 1 + Constants.random.nextInt(4);
      }
    }
    x = nextX(com);
    y = nextY(com);
    float dx = node.getX() - x;
    float dy = node.getY() - y;
    float distance = (float)Math.sqrt(dx * dx + dy * dy);
    steps = (int)(distance / STEP_SIZE);
    if (steps == 0) steps = 1;
    float speed = MIN_SPEED + (MAX_SPEED - MIN_SPEED) * Constants.random.nextFloat();
    delay = (long)(Constants.SECOND * distance / speed);
  }

	public Movement next() {
    if (steps == -1) {
      steps = 0;
      int com = community;
      double p = Constants.random.nextDouble();
      if (p < TRAVEL_PROBABILITY) {
        while (com == community) {
          com = 1 + Constants.random.nextInt(4);
        }
      }
      Movement movement = new Movement();
      movement.x = nextX(com);
      movement.y = nextY(com);
      movement.delay = 0;
      return movement;
    }
    return super.next();
  }

}
